package gttp.nspa.client.adm.activity;

import gttp.nspa.client.adm.event.CustomerActionEvent;
import gttp.nspa.client.adm.place.CustomerPlace;
import gttp.nspa.client.adm.rpc.ICustomerServiceAsync;
import gttp.nspa.shared.om.Customer;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.Inject;

public class CustomerFormActivity extends AbstractActivity implements ICustomerForm.Presenter {

    @Inject
    private ICustomerForm         ui;

    @Inject
    private ICustomerServiceAsync service;

    private EventBus              evb;
    private Customer              editing;

    public void onSaveButtonClicked() {
        String name = ui.name().getText();
        String phone = ui.phone().getText();
        String address = ui.address().getText();
        String email = ui.email().getText();

        if (editing == null) {
            service.create(name, phone, address, email, new AsyncCallback<Customer>() {

                public void onSuccess(Customer result) {
                    editing = result;
                    ui.customerCreated(editing.getId(), editing.getName());
                    evb.fireEvent(CustomerActionEvent.createdEvent(result));
                }

                public void onFailure(Throwable caught) {
                    ui.exceptionCaught(caught);
                }
            });
        } else {
            editing.setName(name);
            editing.setPhone(phone);
            editing.setAddress(address);
            editing.setEmail(email);

            service.save(editing, new AsyncCallback() {

                public void onSuccess(Object result) {
                    ui.customerUpdated(editing.getId(), editing.getName());
                    evb.fireEvent(CustomerActionEvent.updatedEvent(editing));
                }

                public void onFailure(Throwable caught) {
                    ui.exceptionCaught(caught);
                }
            });
        }
    }

    public void onDeleteButtonClicked() {
        if (editing != null && editing.getId() != null) {
            ui.queryDeleting(editing.getId(), editing.getName());
        }
    }

    public void onDeleteConfirmed() {
        service.delete(editing.getId(), new AsyncCallback() {

            public void onSuccess(Object result) {
                ui.customerDeleted(editing.getId(), editing.getName());
                evb.fireEvent(CustomerActionEvent.deletedEvent(editing));
            }

            public void onFailure(Throwable caught) {
                ui.exceptionCaught(caught);
            }

        });
    }

    public void onCancelButtonClicked() {
        ui.canceled();
    }

    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        evb = eventBus;
        ui.setPresenter(this);
        ui.show();
    }

    private void populateModel() {
        if (editing != null) {
            ui.id().setText(editing.getId().toString());
            ui.name().setText(editing.getName());
            ui.address().setText(editing.getAddress());
            ui.phone().setText(editing.getPhone());
            ui.email().setText(editing.getEmail());
        } else {
            ui.id().setText(null);
            ui.name().setText(null);
            ui.address().setText(null);
            ui.phone().setText(null);
            ui.email().setText(null);
        }
    }

    private void loadModel(long theId) {
        service.load(theId, new AsyncCallback<Customer>() {

            public void onSuccess(Customer result) {
                editing = result;
                populateModel();
                ui.readyForEditing(true);
            }

            public void onFailure(Throwable caught) {
                ui.exceptionCaught(caught);
            }
        });
    }

    public void withPlace(CustomerPlace place) {
        if (place.custId != null) {
            ui.prepareForUpdating();
            ui.readyForEditing(false);
            loadModel(place.custId);
        } else if (place.cust != null) {
            ui.prepareForUpdating();
            editing = place.cust;
            populateModel();
        } else {
            ui.prepareForCreating();
            editing = null;
            populateModel();
        }
    }
}
